Control Flow
Conditionals: if / else
Basic
temperatureInFahrenheit = 90
if temperatureInFahrenheit <= 32 {
print("It's very cold. Consider wearing a scarf.")
} else if temperatureInFahrenheit >= 86 {
print("It's really warm. Don't forget to wear sunscreen.")
} else {
print("It's not that cold. Wear a T-shirt.")
}
// Prints "It's really warm. Don't forget to wear sunscreen."
If Expressions
let weatherAdvice = if temperatureInCelsius <= 0 {
"It's very cold. Consider wearing a scarf."
} else if temperatureInCelsius >= 30 {
"It's really warm. Don't forget to wear sunscreen."
} else {
"It's not that cold. Wear a T-shirt."
}
print(weatherAdvice)
// Prints "It's not that cold. Wear a T-shirt."
Checking
nil
in an Optional
let possibleNumber = "123"
let convertedNumber = Int(possibleNumber)
if convertedNumber != nil {
print("convertedNumber contains some integer value.")
}
Ternary
-
Without Ternary :
let contentHeight = 40 let hasHeader = true let rowHeight: Int if hasHeader { rowHeight = contentHeight + 50 } else { rowHeight = contentHeight + 20 } // rowHeight is equal to 90 -
With Ternary :
let contentHeight = 40 let hasHeader = true let rowHeight = contentHeight + (hasHeader ? 50 : 20) // "if hasHeader, 50, else, 20" // rowHeight is equal to 90
Conditionals: match
-
Every
switchstatement must be exhaustive .
Match
-
Basic :
let someCharacter: Character = "z" switch someCharacter { case "a": print("The first letter of the Latin alphabet") case "z": print("The last letter of the Latin alphabet") default: print("Some other character") } // Prints "The last letter of the Latin alphabet" -
Range :
let approximateCount = 62 let countedThings = "moons orbiting Saturn" let naturalCount: String switch approximateCount { case 0: naturalCount = "no" case 1..<5: naturalCount = "a few" case 5..<12: naturalCount = "several" case 12..<100: naturalCount = "dozens of" case 100..<1000: naturalCount = "hundreds of" default: naturalCount = "many" } print("There are \(naturalCount) \(countedThings).") // Prints "There are dozens of moons orbiting Saturn." -
Tuples :
let somePoint = (1, 1) switch somePoint { case (0, 0): print("\(somePoint) is at the origin") case (_, 0): print("\(somePoint) is on the x-axis") case (0, _): print("\(somePoint) is on the y-axis") case (-2...2, -2...2): print("\(somePoint) is inside the box") default: print("\(somePoint) is outside of the box") } // Prints "(1, 1) is inside the box"
Multi-Match
let anotherCharacter: Character = "a"
switch anotherCharacter {
case "a", "A":
print("The letter A")
default:
print("Not the letter A")
}
// Prints "The letter A"
Match Expression
let anotherCharacter: Character = "a"
let message = switch anotherCharacter {
case "a":
"The first letter of the Latin alphabet"
case "z":
"The last letter of the Latin alphabet"
default:
"Some other character"
}
print(message)
// Prints "The first letter of the Latin alphabet"
Value Binding
-
A
switchcase can name the value or values it matches to temporary constants or variables, for use in the body of the case.let anotherPoint = (2, 0) switch anotherPoint { case (let x, 0): print("on the x-axis with an x value of \(x)") case (0, let y): print("on the y-axis with a y value of \(y)") case let (x, y): print("somewhere else at (\(x), \(y))") } // Prints "on the x-axis with an x value of 2" -
Can be used with
wherelet yetAnotherPoint = (1, -1) switch yetAnotherPoint { case let (x, y) where x == y: print("(\(x), \(y)) is on the line x == y") case let (x, y) where x == -y: print("(\(x), \(y)) is on the line x == -y") case let (x, y): print("(\(x), \(y)) is just some arbitrary point") } // Prints "(1, -1) is on the line x == -y"
Fallthrough
let integerToDescribe = 5
var description = "The number \(integerToDescribe) is"
switch integerToDescribe {
case 2, 3, 5, 7, 11, 13, 17, 19:
description += " a prime number, and also"
fallthrough
default:
description += " an integer."
}
print(description)
// Prints "The number 5 is a prime number, and also an integer."
Loops: For
Keywords
-
Classic:
-
continue -
break
-
Ranges
-
Two-sided Ranges :
-
Closed :
-
Defines a range that runs from
atob, and includes the valuesaandb:
for index in 1...5 { print("\(index) times 5 is \(index * 5)") } -
-
Half-Opened :
-
Defines a range that runs from
atob, but doesnโt includeb.
let names = ["Anna", "Alex", "Brian", "Jack"] let count = names.count for i in 0..<count { print("Person \(i + 1) is called \(names[i])") } -
-
-
One-sided Ranges :
-
Closed :
-
Continue as far as possible in one direction
// Includes all the elements of an array from index 2 to the end of the array. for name in names[2...] { print(name) } // Includes all the elements of an array from index 0 to index 2, including index 2. for name in names[...2] { print(name) } -
-
Half-Opened :
for name in names[..<2] { print(name) }
-
Iterating
-
Array :
for (index, value) in shoppingList.enumerated() { print("Item \(index + 1): \(value)") } // Item 1: Six eggs // Item 2: Milk // Item 3: Flour // Item 4: Baking Powder // Item 5: Bananas -
Dictionary :
for (airportCode, airportName) in airports { print("\(airportCode): \(airportName)") } // LHR: London Heathrow // YYZ: Toronto Pearsonfor airportCode in airports.keys { print("Airport code: \(airportCode)") } // Airport code: LHR // Airport code: YYZ for airportName in airports.values { print("Airport name: \(airportName)") } // Airport name: London Heathrow // Airport name: Toronto Pearson
Other Iteration Types
-
Ignoring the iteration value:
let base = 3 let power = 10 var answer = 1 for _ in 1...power { answer *= base } print("\(base) to the power of \(power) is \(answer)") // Prints "3 to the power of 10 is 59049" -
With intervals:
let minuteInterval = 5 for tickMark in stride(from: 0, to: minutes, by: minuteInterval) { // render the tick mark every 5 minutes (0, 5, 10, 15 ... 45, 50, 55) }
Loops: While
var square = 0
var diceRoll = 0
while square < finalSquare {
// roll the dice
diceRoll += 1
if diceRoll == 7 { diceRoll = 1 }
// move by the rolled amount
square += diceRoll
if square < board.count {
// if we're still on the board, move up or down for a snake or a ladder
square += board[square]
}
}
print("Game over!")
Loops: Repeat-While
Differences
-
Performs a single pass through the loop block first, before considering the loopโs condition.
repeat {
// move up or down for a snake or ladder
square += board[square]
// roll the dice
diceRoll += 1
if diceRoll == 7 { diceRoll = 1 }
// move by the rolled amount
square += diceRoll
} while square < finalSquare
print("Game over!")
Deferred
var score = 1
if score < 10 {
defer {
print(score)
}
score += 5
}
// Prints "6"
var score = 3
if score < 100 {
score += 100
defer {
score -= 100
}
// Other code that uses the score with its bonus goes here.
print(score)
}
// Prints "103"
if score < 10 {
defer {
print(score)
}
defer {
print("The score is:")
}
score += 5
}
// Prints "The score is:"
// Prints "6"